import random

import logging
from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from django_redis import get_redis_connection
from rest_framework.generics import GenericAPIView


# url sms_codes/(?P<mobile>1[3-9]\d{9})/$
from rest_framework.response import Response
from rest_framework.views import APIView

from mlh.libs.captcha.captcha import captcha
from verifications import constants

from celery_tasks.sms.tasks import send_sms_code



# 获取在配置文件中定义的logger，用来记录日志
logger = logging.getLogger('django')
"""实现图片验证的逻辑:
   1.需要传一个uuid(唯一的)值到后端，由于是向后端请求数据，所以定义请求方式为get
   2.分析传参的方法，是路径传参还是查询字符串，由于只需要一个标记，所以使用路径传参即可
   3.返回的数据类型，该业务中返回的是图片类型
   4.定义类视图，分析业务逻辑
"""


# 设计该视图的路由为：/image_codes/(?P<image_code_id>[/w-]+/$",在django中分析需要的继承的视图类
class ImageCodeView(APIView):  # 由于该逻辑，不需要使用序列化器验证功能，所以该类就可以实现
    """
    具体业务的实现逻辑
    :param image_code_id
    :return 图片
    """

    def get(self, request, image_code_id):
        # 生成图片验证码
        text, image = captcha.generate_captcha()
        # 把验证码储存在redis(读写频繁，且时效短使用redis数据库存储)中
        # 　连接redis，然后保存验证码在redis中
        redis_conn = get_redis_connection("verify_codes")
        # 使用redis的命名设置保存验证码的键值对：setex(键，有效时间，值)，一般代码中不会写死数字，可以写一个常量文件
        redis_conn.setex("img_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
        # 由于后端返回的数据类型是固定的类型，使用原生的HttpResponse即可
        return HttpResponse(image, content_type="image/jpg")




class SMSCodeView(APIView):
    # 需要传入的参数为手机号mobile
    # 第三方发送过来的短信验证码需要存储在redis，用于验证
    def get(self, request, mobile):
        sms_code = "%06d" % random.randint(0, 999999)
        redis_conn=get_redis_connection("verify_codes")
        pl=redis_conn.pipeline()
        # 把生成的验证码存到redis中
        pl.setex("sms_%s"%mobile,constants.SMS_CODE_REDIS_EXPIES,sms_code)
        # 设置发送短信间隔的标志，防止用户短时间内重复操作
        pl.setex("send_flag_%s"%mobile,constants.SEND_SMS_CODE_INTERVAL,1)
        pl.execute()

        expires=constants.SMS_CODE_REDIS_EXPIES//60
        # 发布发送验证的任务
        send_sms_code.delay(mobile,sms_code,expires,constants.SMS_CODE_TEMP_ID)
        return Response({"message":"ok"})
